package nancal.mp.web.admin

import io.swagger.annotations.Api
import io.swagger.annotations.ApiOperation
import nancal.mp.db.mongo.entity.admin.AdminLoginUser
import nancal.mp.db.mongo.entity.admin.AdminUser
import nancal.mp.db.mongo.mor
import nancal.mp.service.NoFilterProductLineScope
import nbcp.base.annotation.*
import nbcp.base.annotation.mvc.*
import nbcp.base.comm.ApiResult
import nbcp.base.comm.JsonResult
import nbcp.base.comm.ListResult
import nbcp.base.comm.PagerModel
import nbcp.base.db.IdName
import nbcp.base.extend.*
import nbcp.base.json.*
import nbcp.base.utils.Md5Util
import nbcp.base.utils.StringUtil
import nbcp.mvc.sys.*
import nbcp.myoql.db.mongo.*
import nbcp.myoql.db.mongo.extend.linkOr

import org.bson.types.ObjectId
import org.springframework.beans.factory.annotation.Value
import org.springframework.web.bind.annotation.*
import javax.servlet.http.HttpServletRequest

/**
 * Created by CodeGenerator at 2021-03-15 10:31:23
 */
@Api(description = "adminUser", tags = arrayOf("AdminUser"))
@RestController
@RequestMapping("/admin/admin-user")
class AdminUserAutoController {

    data class AdminUserWithProducctLineModel(var productLines: List<IdName> = listOf()) : AdminUser() {

    }

    @ApiOperation("列表")
    @PostMapping("/list")
    fun list(
        id: String, //当列表列新一条后，刷新时使用
        duty: String,
        name: String,
        @org.springframework.web.bind.annotation.RequestBody query: PagerModel<Any?>,
        request: HttpServletRequest
    ): ListResult<AdminUserWithProducctLineModel> {

        mor.admin.adminUser.query()
            .apply {
                if (id.HasValue) {
                    this.where { it.id mongoEquals id }
                }

                if (duty.HasValue) {
                    this.where { it.duty mongoLike duty }
                }

                if (name.HasValue) {
                    this.where { (it.name mongoLike name) linkOr (it.loginName mongoLike name) }
                }
            }
            .withPager(query)
            .toListResult(AdminUserWithProducctLineModel::class.java)
            .apply {

                usingScope(NoFilterProductLineScope()) {
                    var userIds = this.data.map { it.id }.toList();

                    var productLines = mor.dev.productLine.query()
                        .linkOr(
                            { it.pm.id mongoIn userIds },
                            { it.lm.id mongoIn userIds },
                            { it.leader.id mongoIn userIds },
                            { it.developers.id mongoIn userIds }
                        )
                        .toList()


                    this.data.forEach { user ->
                        var userProducts = productLines.filter { pl ->
                            pl.pm.id == user.id ||
                                    pl.lm.id == user.id || pl.leader.id == user.id ||
                                    pl.developers.any { it.id == user.id }
                        }.toList().map { IdName(it.id, it.name) };

                        user.productLines = userProducts;
                    }
                }
                return this
            }
    }

    @ApiOperation("详情")
    @PostMapping("/dutys")
    fun dutys(
        request: HttpServletRequest
    ): ListResult<String> {
        mor.admin.adminUser.query()
            .select { it.duty }
            .toList(String::class.java)
            .toSet()
            .apply {
                return ListResult.of(this);
            }
    }

    @ApiOperation("详情")
    @PostMapping("/detail/{id}")
    fun detail(
        @Require id: String,
        request: HttpServletRequest
    ): ApiResult<AdminUserWithProducctLineModel> {
        mor.admin.adminUser.queryById(id)
            .toEntity(AdminUserWithProducctLineModel::class.java)
            .apply {
                if (this == null) {
                    return ApiResult.error("找不到数据")
                }

                usingScope(NoFilterProductLineScope()) {

                    var productLines = mor.dev.productLine.query()
                        .linkOr(
                            { it.pm.id mongoEquals id },
                            { it.lm.id mongoEquals id },
                            { it.leader.id mongoEquals id },
                            { it.developers.id mongoEquals id }
                        )
                        .toList()
                        .map { IdName(it.id, it.name) };

                    this.productLines = productLines
                }

                return ApiResult.of(this)
            }
    }

    @Value("\${app.default-password:1234}")
    lateinit var defPassword: String;


    @GetMapping("/fix")
    fun fix() {
        mor.admin.adminUser.query().toList()
            .forEach { user ->

                var adminLoginUser = mor.admin.adminLoginUser.queryByLoginName(user.loginName).toEntity()

                if (adminLoginUser == null) {
                    return@forEach
                }

                if (adminLoginUser.id == user.id) {
                    return@forEach
                }

                mor.admin.adminLoginUser.deleteById(adminLoginUser.id!!).exec()


                adminLoginUser.id = user.id;
                mor.admin.adminLoginUser.doInsert(adminLoginUser);

            }
    }

    @ApiOperation("更新")
    @PostMapping("/save")
    fun save(
        @RequestBody entity: AdminUser,
        request: HttpServletRequest
    ): ApiResult<String> {
        //鉴权
        var userId = request.UserId;


        mor.admin.adminUser.updateWithEntity(entity)

            .run {
                if (entity.id.HasValue) {
                    var ori_user = mor.admin.adminUser.queryById(entity.id).toEntity()
                    if (ori_user == null) {
                        throw RuntimeException("找不到用户信息")
                    }

                    mor.admin.adminLoginUser.update()
                        .where { it.loginName mongoEquals ori_user.loginName }
                        .set { it.loginName to entity.loginName }
                        .set { it.mobile to entity.mobile }
                        .set { it.email to entity.email }
                        .exec();

                    return@run this.execUpdate()
                } else {
                    entity.id = ObjectId().toString()
                    var ent = AdminLoginUser();
                    ent.id = entity.id
                    ent.loginName = entity.loginName
                    ent.mobile = entity.mobile;
                    ent.email = entity.email;
                    ent.password = Md5Util.getBase64Md5(defPassword);
                    mor.admin.adminLoginUser.doInsert(ent);

                    return@run this.execInsert()
                }
            }
            .apply {
                if (this == 0) {
                    return ApiResult.error("更新失败")
                }

                return ApiResult.of(entity.id)
            }
    }


    @ApiOperation("更新")
    @PostMapping("/save-me")
    fun saveMe(
        @org.springframework.web.bind.annotation.RequestBody entity: AdminUser,
        request: HttpServletRequest
    ): ApiResult<String> {
        var userId = request.UserId;
        mor.admin.adminUser.updateById(userId)
            .set { it.name to entity.name }
            .set { it.mobile to entity.mobile }
            .set { it.email to entity.email }
            .set { it.logo.url to entity.logo.url }
            .exec()
            .apply {
                if (this == 0) {
                    return ApiResult.error("更新失败")
                }

                return ApiResult.of(entity.id)
            }
    }


    class PasswordVO {
        var password: String = ""
    }

    @ApiOperation("重置密码")
    @PostMapping("/reset-pwd/{userId}")
    fun resetPwd(
        request: HttpServletRequest,
        @RequestBody passwordVO: PasswordVO
    ): ApiResult<String> {
        var pwd = Md5Util.getBase64Md5(passwordVO.password);
        var userId = request.UserId;
        mor.admin.adminLoginUser.updateById(userId)
            .set { it.password to pwd }
            .exec()
            .apply {
                if (this == 0) {
                    return ApiResult.error("重置密码失败")
                }

                return ApiResult.of(passwordVO.password)
            }
    }


    @ApiOperation("删除")
    @PostMapping("/delete/{id}")
    fun delete(
        @Require id: String,
        request: HttpServletRequest
    ): JsonResult {
        //鉴权
        var userId = request.UserId

        var entity = mor.admin.adminUser.queryById(id).toEntity()
        if (entity == null) {
            return JsonResult.error("找不到数据")
        }

        mor.admin.adminLoginUser.deleteByLoginName(entity.loginName).exec();

        mor.admin.adminUser.deleteById(id)
            .exec()
            .apply {
                if (this == 0) {
                    return JsonResult.error("删除失败")
                }
                //实体上配置垃圾箱功能，可物理删除，会自动移到垃圾箱。
                return JsonResult()
            }
    }
}

